home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i052: NN Newsreader, release 6.4, Part18/21
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: c0167a12 57a96eb0 4c755aec 80ad09d7
-
- Submitted-by: "Kim F. Storm" <storm@texas.dk>
- Posting-number: Volume 22, Issue 52
- Archive-name: nn6.4/part18
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: contrib/recmail.c contrib/recmail.sh doc/NEWS-6.3 inst.sh
- # news.c reroute.c unshar.c xmakefile
- # Wrapped by storm@texas.dk on Sun May 6 18:20:14 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 18 (of 22)."'
- if test -f 'contrib/recmail.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'contrib/recmail.c'\"
- else
- echo shar: Extracting \"'contrib/recmail.c'\" \(7717 characters\)
- sed "s/^X//" >'contrib/recmail.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1990 Tom Dawes-Gamble.
- X * For Copyright restrictions see the README file distributed with nn.
- X *
- X * Mail sender for nn with C news and smail.
- X *
- X * Written by Tom Dawes-Gamble Texas Instruments Ltd, Bedford England.
- X *
- X * e-mail tmdg@texins.uucp
- X * uucp ..!ukc.co.uk!pyrltd!miclon!texins!tmdg
- X *
- X * When I installed nn with Cnews I could not find an equivalent
- X * to the Bnews recmail so I wrote this to do the job.
- X * It seems to work for me.
- X * I have no idea how this will work for mailers other than smail
- X *
- X * YOU WILL need to look at the way get_host_name works for you system
- X *
- X * If you use this program please let me know so that I can mail you
- X * any enhancements.
- X *
- X */
- X
- X/* you can use the smail defs if required */
- X#ifdef SMAIL_DEFS_H
- X#include SMAIL_DEFS_H
- X#else
- X#define MYDOM ".uucp"
- X#endif /* SMAIL_DEFS_H */
- X
- X#define MAILER "/bin/smail" /* The pathname of your mailer */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <string.h>
- X#include <pwd.h>
- X#include <sys/utsname.h>
- X#include <sys/types.h>
- X#include <time.h>
- X
- X/* where is the local time zone name ? */
- X
- X /* xenix 2.3.2 has this in the tm structure */
- X/*#define TIMEZONE_NAME(tm) ((tm)->tm_name) /* */
- X /* some systems have it here */
- X#define TIMEZONE_NAME(tm) (asctime(tm)?tzname[(tm)->tm_isdst?1:0]:"") /* */
- X
- Xextern char *getlogin();
- Xextern char *getenv();
- Xextern char *malloc();
- Xextern char *mktemp();
- Xextern struct passwd *getpwnam();
- Xvoid get_host_name();
- X
- Xchar *day_name[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- X
- Xchar *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
- X
- Xchar *mail_template = "/tmp/rmXXXXXX";
- Xchar *mail_spool = "/tmp/rmXXXXXX";
- X
- X#undef BUFSIZ
- X#define BUFSIZ 1024 /* a 1024 byte buffer should be enough */
- X
- X#define ERROR_MSG_0 "%s: Unable to read stdin ** Error = %d\n"
- X#define ERROR_MSG_1 "%s: Unable to create spool file ** Error = %d\n"
- X
- XFILE *sfd, *fopen();
- X
- Xvoid send_the_message();
- Xvoid build_the_header();
- X
- Xint main(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char inbuff[BUFSIZ]; /* Buffer for stdin */
- X char pbuff[BUFSIZ]; /* Buffer to hold the name of recipients */
- X char **tolist, *tonames[100]; /* I think that should cope for now */
- X
- X if (argc != 1) {
- X (void) fprintf(stderr,
- X "%s does not allow any arguments yet!\n", argv[0]);
- X exit(1);
- X }
- X tolist = tonames;
- X
- X/* FIX this could be much better */
- X *tolist++ = MAILER;
- X *tolist++ = "-f";
- X *tolist++ = mktemp(strcpy(mail_spool, mail_template));
- X *tolist = pbuff;
- X
- X if ((sfd = fopen(mail_spool, "w")) == NULL){
- X (void) fprintf(stderr, ERROR_MSG_1, argv[0], MAILER, errno);
- X exit(1);
- X }
- X build_the_header();
- X
- X /* Now send the mail down the tube */
- X
- X while((fgets(inbuff, BUFSIZ, stdin)) == inbuff){
- X /* strip blind copies */
- X if (strncmp(inbuff, "Bc: ", 4)){ /* true if not Bc: */
- X (void) fprintf(sfd, "%s", inbuff);
- X }
- X if (!strncmp(inbuff, "To: ", 4)){
- X tolist += get_names(inbuff, tolist);
- X } else if (!strncmp(inbuff, "Cc: ", 4)){
- X tolist += get_names(inbuff, tolist);
- X } else if (!strncmp(inbuff, "Bc: ", 4)){
- X tolist += get_names(inbuff, tolist);
- X } else if (!strcmp(inbuff, "\n")){
- X break;
- X }
- X }
- X while((fgets(inbuff, BUFSIZ, stdin)) == inbuff){
- X (void) fprintf(sfd, "%s", inbuff);
- X }
- X (void) fflush(sfd);
- X (void) fclose(sfd);
- X *tolist = NULL;
- X send_the_message(tonames);
- X exit(0);
- X}
- X
- Xget_names(line_buffer, to_names)
- Xchar *line_buffer;
- Xchar **to_names;
- X{
- X char *curr_name;
- X char *next_name;
- X int name_count;
- X
- X name_count = 0;
- X (void) strip_comments(line_buffer);
- X (void) check_for_bracket(line_buffer);
- X while (next_name = strchr(line_buffer, ' ')){
- X *next_name++ = '\0';
- X while (*next_name == ' ')
- X next_name++;
- X curr_name = *to_names;
- X curr_name += strlen(curr_name) + 1;
- X (void) strcpy(*to_names++, line_buffer);
- X *to_names = curr_name;
- X (void) strcpy(line_buffer, next_name);
- X name_count++;
- X }
- X if (strlen(line_buffer)){
- X curr_name = *to_names;
- X curr_name += strlen(curr_name) + 1;
- X (void) strcpy(*to_names++, line_buffer);
- X *to_names = curr_name;
- X name_count++;
- X }
- X return name_count;
- X}
- X
- X/* FIX Correct the order of the head lines */
- Xvoid
- Xbuild_the_header()
- X{
- X struct passwd *login, *getpwnam(), *getpwuid();
- X struct passwd *effective;
- X struct tm *gmt;
- X struct tm *loc;
- X long tics;
- X char hostname[9];
- X
- X if(!(login = getpwnam(getlogin())))
- X login = getpwuid(getuid());
- X get_host_name(hostname);
- X gmt = (struct tm *) malloc(sizeof (struct tm));
- X tics = time((long *) 0);
- X loc = gmtime(&tics );
- X *gmt = *loc;
- X loc = localtime(&tics );
- X (void) fprintf(sfd, "%s\n", login->pw_name);
- X/* the Reply to: line doesn't look nice on xenix */
- X (void) fprintf(sfd, "Reply-To: %s@%s%s (%s)\n", login->pw_name,
- X hostname, MYDOM, login->pw_comment);
- X/* I'm not sure about this so if it's wrong please tell me */
- X if (getuid() != login->pw_uid){
- X effective = getpwuid(getuid());
- X (void) fprintf(sfd, "Sender: %s@%s%s (%s)\n",
- X effective->pw_name, hostname, MYDOM,
- X effective->pw_comment);
- X }
- X (void) fprintf(sfd, "Message-Id: <%d%02d%02d%02d%02d.%s%05d@%s%s>\n",
- X gmt->tm_year, (gmt->tm_mon + 1), gmt->tm_mday,
- X gmt->tm_hour, gmt->tm_min,
- X "AA", getpid(), hostname, MYDOM);
- X (void) fprintf(sfd, "Date: %s, %d %s %d %02d:%02d:%02d GMT\n",
- X day_name[gmt->tm_wday], gmt->tm_mday, month[gmt->tm_mon],
- X gmt->tm_year, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
- X (void) fprintf(sfd, "From: %s@%s%s \(%s\)\n",
- X login->pw_name, hostname, MYDOM, login->pw_comment);
- X/* To help local people know when you sent the mail */
- X if (loc->tm_isdst || strncmp(TIMEZONE_NAME(loc), "GMT", 3))
- X (void) fprintf(sfd,
- X "X-Local-time: %s, %d %s %d %02d:%02d:%02d %s\n",
- X day_name[loc->tm_wday], loc->tm_mday,
- X month[loc->tm_mon], loc->tm_year, loc->tm_hour,
- X loc->tm_min, loc->tm_sec, TIMEZONE_NAME(loc));
- X}
- X
- Xvoid
- Xsend_the_message(arg_list)
- Xchar *arg_list[];
- X{
- X int cid, rid;
- X int child_stat;
- X
- X /*fprintf(stderr, "%s\n", *arg_list);*/
- X
- X if (cid = fork()){
- X if ( (rid = wait((int *)&child_stat)) == -1){
- X (void) fprintf(stderr, "%d %d %d %x\n",
- X cid, rid, errno, child_stat);
- X } else {
- X cid = 0;
- X/* FIX I would like to unlink but can't since it causes smail to fail */
- X /*(void) unlink(mail_spool);*/
- X }
- X } else {
- X (void) execvp(*arg_list, arg_list);
- X }
- X return;
- X
- X}
- X
- X/* FIX This is for xenix System V can use unames */
- Xvoid
- Xget_host_name(hostname)
- Xchar *hostname;
- X{
- X FILE *hfd;
- X char *h;
- X
- X hfd = fopen("/etc/systemid", "r");
- X if (hfd == NULL) {
- X#ifdef HOSTNAME
- X strcpy(hostname, HOSTNAME); /* maybe from smail defs.h */
- X#else
- X strcpy(hostname, "UNKNOWN");
- X#endif
- X return;
- X }
- X h = fgets(hostname, 9, hfd);
- X (void) fclose(hfd);
- X while (*h != '\0')
- X if (*h == '\n')
- X *h = '\0';
- X else
- X h++;
- X return;
- X}
- X
- X/* remove first word and any comments */
- X/* Note comment is totaly removed and replaced by space */
- X/* this may need changeing */
- X/* all space will be compressed to a single space */
- X/* FIX required to handle tabs at the moment \tword starting
- X a line will be lost but thats not what I want */
- X
- Xstrip_comments(buff)
- Xchar *buff;
- X{
- X char *begin, *end;
- X
- X if (end = strchr(buff, ' ')){
- X while (*end == ' ') end++;
- X (void) strcpy(buff, end);
- X }
- X while(begin = strchr(buff, '(')){
- X end = strchr(begin, ')');
- X end++;
- X (void) strcpy(begin, end);
- X }
- X end = strchr(buff, '\n');
- X *end = '\0';
- X return;
- X}
- X
- X
- X/* This routine test the line for <machine readable field>
- X if found then only those fields are left */
- X
- Xcheck_for_bracket(buff)
- Xchar *buff;
- X{
- X char *begin, *end;
- X
- X while(begin = strchr(buff, '<')){
- X begin++;
- X (void) strcpy(buff, begin);
- X end = strchr(begin, '>');
- X *end = ' ';
- X buff = end + 1;
- X }
- X return;
- X}
- X
- END_OF_FILE
- if test 7717 -ne `wc -c <'contrib/recmail.c'`; then
- echo shar: \"'contrib/recmail.c'\" unpacked with wrong size!
- fi
- # end of 'contrib/recmail.c'
- fi
- if test -f 'contrib/recmail.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'contrib/recmail.sh'\"
- else
- echo shar: Extracting \"'contrib/recmail.sh'\" \(1657 characters\)
- sed "s/^X//" >'contrib/recmail.sh' <<'END_OF_FILE'
- X#!/bin/sh
- X# This is my version of a mailer that parses the To: lines and invokes the
- X# domain-based mailer mfr Jul 89
- X
- Xexport PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$)
- X
- X# System dependencies
- X
- Xmailer="/usr/local/smtp"
- X# your site name
- Xcase undef in
- Xdefine) sitename=`hostname` ;;
- Xundef) sitename="puppsr" ;;
- Xesac
- X
- Xtest=test
- Xsed=/bin/sed
- Xecho=/bin/echo
- Xcat=/bin/cat
- Xgrep=/bin/grep
- Xrm=/bin/rm
- X
- Xdotdir=${DOTDIR-${HOME-$LOGDIR}}
- Xtmpart=$dotdir/.letter
- X
- X $cat >$tmpart
- X
- X case $mailer in
- X *sendmail)
- X $mailer -t <$tmpart
- X ;;
- X# but recmail does not know about Bcc, alas
- X *recmail)
- X $mailer <$tmpart
- X ;;
- X *)
- X set X `$sed <$tmpart -n -e '/^To:/{' -e 's/To: *//p' -e q -e '}'`
- X shift
- X set X "$@" `$sed <$tmpart -n -e '/^Cc:/{' -e 's/Cc: *//p' -e q -e '}'`
- X shift
- X set X "$@" `$sed <$tmpart -n -e '/^Bcc:/{' -e 's/Bcc: *//p' -e q -e '}'`
- X shift
- X for i in "$@"
- X do
- X thost=`echo $i | cut -s -d@ -f2`
- X recip=`echo $i | cut -s -d@ -f1`
- X sender=${LOGNAME}@${sitename}
- X $grep -v "^Bcc:" <$tmpart | $mailer $thost $sender $recip
- X done
- X ;;
- X esac
- X case $? in
- X 0)
- X state=cleanup
- X ;;
- X *)
- X state=rescue
- X ;;
- X esac
- Xcase $state in
- X rescue)
- X $cat $tmpart >> ${HOME-$LOGDIR}/dead.letter
- X $echo "Message appended to ${HOME-$LOGDIR}/dead.letter"
- X $echo "A copy may be temporarily found in $tmpart"
- X exit
- X ;;
- X cleanup)
- X case "${MAILRECORD-none}" in
- X none)
- X ;;
- X *) if $cat $tmpart >> $MAILRECORD; then
- X $echo "Article appended to $MAILRECORD"
- X else
- X $echo "Cannot append to $MAILRECORD"
- X fi
- X ;;
- X esac
- X exit
- X ;;
- X esac
- Xdone
- X
- X
- END_OF_FILE
- if test 1657 -ne `wc -c <'contrib/recmail.sh'`; then
- echo shar: \"'contrib/recmail.sh'\" unpacked with wrong size!
- fi
- # end of 'contrib/recmail.sh'
- fi
- if test -f 'doc/NEWS-6.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/NEWS-6.3'\"
- else
- echo shar: Extracting \"'doc/NEWS-6.3'\" \(6036 characters\)
- sed "s/^X//" >'doc/NEWS-6.3' <<'END_OF_FILE'
- XNew features in release 6.3 (compared to release 6.1.5):
- X--------------------------------------------------------
- X
- XMajor improvements:
- X NNTP support
- X nn can now use/update .newsrc (to a limited extent)
- X Presentation of article header can be customized
- X Full macro support
- X Full folder maintenance
- X Completion help available using '?' key
- X Backup of rc file works!
- X Much faster nngoback - not based on history file.
- X
- XChanges in standard key mappings:
- X reading mode Z -> goto-menu
- X reading mode N -> next-group
- X reading mode p -> previous (was print)
- X reading mode P -> print (was previous)
- X
- XNew commands:
- X leave-article
- X :define
- X :man
- X :map both ...
- X :patch
- X :pwd
- X :rmail
- X :show groups unsub
- X
- XNew variables:
- X backup (New functionality! It is set by default)
- X confirm-append
- X default-save-file
- X delay-redraw
- X header-lines
- X mail
- X mail-format
- X mark-overlap
- X newsrc
- X overlap
- X patch-cmd
- X quick-save
- X retry-on-error
- X save-report
- X word-key
- X
- XNew options:
- X -m
- X -s/ (regexp matching)
- X
- XDescription of new features (in mixed order):
- X---------------------------------------------
- X
- XNNTP support has been added (thanks to Rene Seindal @ diku.dk).
- X
- XOnline manual.
- X
- XRegular expression search in reading mode: / and .
- X
- XRegular expression matching for subjects in -s/ option and G=/ command.
- X
- XArticles can be saved in a mail compatible format by setting the
- Xmail-format variable.
- X
- XThe article selection save files are now kept in network format if
- XNETWORK_DATABASE is defined, so reading news from different machines
- Xshould now work in a heterogeneous environment.
- X
- XAdded $F which expands to the group name with / instead of . E.g. $F
- Xin rec.music.synth produces rec/music/synth
- X
- XFolder name "+" is expanded to the file name found in the new
- Xdefault-save-file variable (default +$F).
- X
- XWhen saving articles, the prompting for a file name can be disabled by
- Xsetting the quick-save variable (saving will be done in the default
- Xsave file).
- X
- Xnn will ask for confirmation before appending to existing files when
- Xconfirm-append is set.
- X
- XThe message after each save can be disabled by unsetting the
- Xsave-report variable.
- X
- XThe manual has been corrected to use the proper names for the
- Xmail-record and news-record variables.
- X
- X:unshar will create the directory if is does not exist.
- X
- XCustomized article header presentation through setting of header-lines
- Xvariable.
- X
- XComplete variable settings are now shown by :set
- X
- XFull macro support - you can now bind any sequence of commands to a
- Xsingle key (see the define command).
- X
- XIndividual articles in a folder can now be cancelled! I.e. folders
- Xare now fully supported: you can save, print, respond to, and cancel
- Xseparate articles in the folders created by nn. (Try the G +folder command).
- X
- XA global init file is now supported rather than just a global sequence file.
- X(You should avoid using the sequence file, because it might go away in
- Xa future release.)
- X
- XNn will now remember which articles you have seen on the menu (but not
- Xnecessarily selected) when you quit. Confirming the question "use old
- Xselections" now also implies that nn will start on the same menu page
- Xas the one you quitted on.
- X
- XThere is a retry-on-error variable which can be set to a number of
- Xtimes attempts to open an article should be done before giving up.
- X
- XYou can now specify per group default save files in the init file (in
- Xthe group sequence).
- X
- XS+ is an addition to the old S* command which saves all the selected
- Xarticles in the group!
- X
- XWhen you have given a command that clears the screen, the screen is
- Xnow redrawn by default when the command terminates. To get the 6.1
- Xbehaviour (prompt for a new : command), you must set the delay-redraw
- Xvariable.
- X
- XWhen input completion is possible, you can now use the ? key to get a
- Xlist of the possible completions.
- X
- XCompletion is now possible when entering an extended command
- X(:command) - both for the command name itself and the arguments.
- X(The only exception is when entering the VALUE of a variable.)
- X
- XThe 'backup' variable now works "the right way": It makes a backup of
- Xthe rc file on start-up. nn can then update the rc file after reading
- Xeach group (increased security), and still restore the old rc file
- Xwith the :q! command. The backup variable is now set by default.
- X
- XYou can set the 'mail' variable to make nn check for the arrival of
- Xmail, and you can use the ':rmail' command to read the mail! (But it
- Xis not a full mail interface, e.g. you cannot delete messages, cc:
- Xfields are not supported if you reply to a message, etc.)
- X
- Xnn will now synchronize with the .newsrc file if the "newsrc" variable
- Xis set. However, it does NOT understand about individual articles
- Xthat are marked as unread (e.g. 5-8 in 1-4,9-24) - it will silently
- Xmark such articles as read (e.g. read the above as 1-24).
- X I don't know anybody who uses this, but if somebody wants to improve
- Xon it, feel free to do it. If you just want to to use rn from time to
- Xtime, the current support will be sufficient if you always read all
- Xthe articles in a group once you have started reading it (or you read
- Xthe articles in the normal article number order).
- X
- XWhen saving an article with a full or partial header in a folder,
- Xlegal article header lines in the body of the article are now
- Xescaped with a tilde, e.g. ~From: ....., to avoid having the
- Xarticles split improperly when the folder is later opened by nn.
- X
- XThere is a new C)onf command to nnadmin to print the current
- Xconfiguration (directories, files, network, etc.).
- X
- XThe G (goto-group) command now allows you to jump to an unread group
- Xin the group sequence without entering a new recursive menu level.
- X
- XThe manual nn.1 has been clarified regarding the effect of options:
- XThe init file is read prior to parsing the options, and the options
- Xwill TOGGLE the CURRENT value of boolean variables.
- X
- X
- XRemoved backwards compatibility
- X-------------------------------
- X
- XSupport for upgrading from release 3, 4, or 5 has been removed, since
- Xthe sites using these releases have all updated to 6.1.
- X
- XAlso the support for pre 2.11 news has been removed (OLD_NEWS).
- X
- END_OF_FILE
- if test 6036 -ne `wc -c <'doc/NEWS-6.3'`; then
- echo shar: \"'doc/NEWS-6.3'\" unpacked with wrong size!
- fi
- # end of 'doc/NEWS-6.3'
- fi
- if test -f 'inst.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'inst.sh'\"
- else
- echo shar: Extracting \"'inst.sh'\" \(7589 characters\)
- sed "s/^X//" >'inst.sh' <<'END_OF_FILE'
- X
- X# (Large) prefix inserted above by Make
- X
- X# BSD systems keep chown in /etc
- XPATH="$PATH:/etc"
- X
- Xcase "$1" in
- Xmkdir)
- X if [ -n "$2" -a ! -d "$2"/. ]
- X then
- X mkdir $2
- X if [ ! -d "$2" ] ; then
- X echo "Cannot create directory $2"
- X exit 1
- X fi
- X chmod $3 $2
- X chgrp $GROUP $2
- X chown $OWNER $2
- X echo Created directory $2
- X fi
- X exit 0
- X ;;
- Xcopy)
- X cp $4 $3
- X chmod $2 $3/$4
- X chgrp $GROUP $3/$4
- X chown $OWNER $3/$4
- X echo "$4 -> $3/$4"
- X exit 0
- X ;;
- Xchmod)
- X chmod $2 $3
- X chgrp $GROUP $3
- X chown $OWNER $3
- X exit 0
- X ;;
- X
- Xinews)
- X if [ ! -d "${INEWS_DIR}"/. ]
- X then
- X ../inst mkdir ${INEWS_DIR} 755 || exit 1
- X fi
- X echo Installing $2 in $INEWS
- X cp $2 $INEWS && ../inst chmod 755 $INEWS
- X exit 0
- X ;;
- Xesac
- X
- Xset -u
- X
- X(
- Xif $NNTP
- Xthen
- X :
- Xelse
- X if [ ! -d "$SPOOL"/. ]
- X then
- X echo Error: News spool directory $SPOOL not found.
- X fi
- X
- X if [ ! -d "$NLIB"/. ]
- X then
- X echo Error: News lib directory $NLIB not found.
- X fi
- Xfi
- X
- Xset $INEWS
- Xif [ ! -f "$1" ]
- Xthen
- X echo ERROR: Inews program $INEWS not found.
- Xfi
- X
- Xset $RECMAIL
- Xif [ ! -f "$1" ]
- Xthen
- X echo ERROR: Mailer program $RECMAIL not found.
- Xfi
- X) > ErrorCheck
- X
- Xif [ -s ErrorCheck ]
- Xthen
- X cat ErrorCheck
- X echo "Hit return to continue"
- X read X
- Xfi
- Xrm -f ErrorCheck
- X
- XLOOP=true
- Xwhile $LOOP
- Xdo
- X
- Xif [ $# -ge 1 ]
- Xthen
- X OPT="$1"
- X shift
- X if [ $# -eq 0 ]
- X then
- X LOOP=false
- X fi
- X PAUSE=false
- Xelse
- X PAUSE=true
- X
- Xecho
- Xecho
- Xecho "INSTALLATION"
- Xecho ""
- Xecho "1) Master programs (machine dependent)"
- Xecho "2) User programs (machince dependent, shareable)"
- Xecho "3) Help files and auxiliary programs (shareable)"
- Xecho "4) Documentation (shareable)"
- Xecho "5) Online manual (shareable with 3)"
- Xecho ""
- Xecho "INIT) Initialize database"
- Xecho ""
- Xecho "s) Server installation: 1 + 2 + 3 + 4 + 5"
- Xecho "n) Network installation: 2 + 3 + 4 + 5"
- Xecho "m) Master installation: 1"
- Xecho "c) Client installation: 2"
- Xecho "u) Update after patch"
- Xecho "q) Quit"
- Xecho ""
- Xif ./usercheck 0 ; then
- X :
- Xelse
- X echo "Warning: not running as super user"
- X echo ""
- Xfi
- X${AWK} 'BEGIN{printf "Select option: "}' < /dev/null
- Xread OPT
- Xecho
- X
- Xfi
- X
- Xcase $OPT in
- X
- Xs*|a*)
- X OPT="master bin aux help online man"
- X ;;
- Xu*)
- X OPT=""
- X if [ -f "$MASTER/nnmaster" ]
- X then
- X OPT="$OPT master"
- X fi
- X if [ -f "$BIN/nn" ]
- X then
- X OPT="$OPT bin"
- X fi
- X if [ -f "$LIB/aux" ]
- X then
- X OPT="$OPT aux help"
- X fi
- X if [ -f "$DMAN_DIR/nnmaster.$DMAN_SECT" ]
- X then
- X OPT="$OPT man"
- X fi
- X if [ -f "$HELP/Manual" ]
- X then
- X OPT="$OPT online"
- X fi
- X ;;
- X1|m)
- X OPT=master
- X ;;
- Xn)
- X OPT="bin aux help online man"
- X ;;
- X2|c)
- X OPT=bin
- X ;;
- X3)
- X OPT="aux help"
- X ;;
- Xx)
- X OPT=aux
- X ;;
- Xh)
- X OPT=help
- X ;;
- X4)
- X OPT="man"
- X ;;
- X5)
- X OPT="online"
- X ;;
- XINIT)
- X OPT=init
- X ;;
- Xq*|"")
- X if [ -f $MASTER/nnmaster -a ! -f $MASTER/MPID ]
- X then
- X echo "Remember to restart $MASTER/nnmaster"
- X fi
- X exit 0
- X ;;
- X*)
- X echo "Unrecognized option: $OPT"
- X exit 1
- X ;;
- Xesac
- X
- Xfor OP in $OPT
- Xdo
- Xcase "$OP" in
- X
- Xmaster)
- X ./inst mkdir $MASTER 755 || exit 1
- X
- X if [ -f $MASTER/nnmaster ]
- X then
- X (
- X cd $MASTER
- X if [ -f MPID ]
- X then
- X echo "Stopping running master..."
- X kill -1 `cat MPID`
- X sleep 5
- X rm -f MPID
- X fi
- X mv nnmaster nnmaster.old
- X )
- X fi
- X
- X echo Installing master in $MASTER
- X
- X for prog in $MASTER_PROG
- X do
- X ./inst copy 755 $MASTER $prog
- X done
- X
- X chmod 4750 $MASTER/nnmaster
- X ;;
- X
- Xbin)
- X echo
- X if [ ! -d "$BIN"/. ]
- X then
- X echo Directory $BIN does not found!
- X exit 1
- X fi
- X
- X echo Installing user programs in $BIN
- X
- X if [ -f $BIN/nn ]
- X then
- X (
- X cd $BIN
- X mv nn nn.old
- X rm -f $BIN_PROG $BIN_LINK
- X )
- X fi
- X
- X for prog in $BIN_PROG
- X do
- X ./inst copy 755 $BIN $prog
- X done
- X
- X for link in $BIN_LINK
- X do
- X ln $BIN/nn $BIN/$link
- X echo $link linked to nn
- X done
- X
- X if [ -f $BIN/nnacct ] ; then
- X chmod 4755 $BIN/nnacct
- X echo nnacct is setuid ${OWNER}.
- X fi
- X ;;
- X
- Xaux)
- X echo
- X ./inst mkdir $LIB 755 || exit 1
- X
- X echo Installing auxiliary programs in $LIB
- X
- X for prog in $LIB_PROG
- X do
- X ./inst copy 755 $LIB $prog
- X done
- X
- X ./mkprefix conf > ${LIB}/conf
- X grep "^#" config.h |
- X sed -e '/_MAN_/d' -e 's/[ ]*\/\*.*$//' >> ${LIB}/conf
- X ./inst chmod 644 ${LIB}/conf
- X ;;
- X
- Xhelp)
- X ./inst mkdir $HELP 755 || exit 1
- X
- X echo
- X echo Installing help files in $HELP
- X
- X for h in `grep '^help/' MANIFEST | sed 's/^help\/\([a-z0-9.]*\).*$/\1/'`
- X do
- X ./cvt-help < help/$h > $HELP/$h
- X ./inst chmod 644 $HELP/$h
- X echo $h
- X done
- X ;;
- X
- Xman)
- X echo
- X echo Installing manuals
- X
- X {
- X echo $UMAN_DIR $UMAN_SECT .1
- X echo $SMAN_DIR $SMAN_SECT .1m
- X echo $DMAN_DIR $DMAN_SECT .8
- X } |
- X while read DIR SECT SRC
- X do
- X
- X if [ -d "$DIR"/. -a -w "$DIR"/. ]
- X then
- X for i in man/*$SRC
- X do
- X MAN=`basename ${i} $SRC`
- X NEW=$DIR/${MAN}.$SECT
- X cp $i $NEW
- X ./inst chmod 644 $NEW
- X echo $MAN in $NEW
- X done
- X else
- X echo $DIR not found or not writeable
- X fi
- X done
- X ;;
- X
- Xonline)
- X ./inst mkdir $HELP 755 || exit 1
- X
- X MAN=$HELP/Manual
- X
- X echo
- X echo "Formatting online manual $MAN"
- X echo ".... (continues in background) ...."
- X
- X rm -f $MAN
- X
- X (
- X sed -e 's/\\f[BPI]//g' \
- X -e 's/\\-/-/g' -e 's/\\&//g' -e 's/\\e/\\/g' \
- X -e '/^\.\\"ta/p' -e '/^\.\\"/d' \
- X -e '/^\.nf/d' -e '/^\.fi/d' \
- X -e '/^\.if/d' -e '/^\.ta/d' -e '/^\.nr/d' \
- X -e '/^\.in/d' -e 's/^\.[BI] //' \
- X `grep '^man/' MANIFEST | ${AWK} '{print $1}'` |
- X ${AWK} -f format.awk - > $MAN
- X
- X ./inst chmod 644 $MAN
- X ) &
- X ;;
- X
- Xinit)
- X echo
- X ./inst mkdir "$DB" 755 || exit 1
- X ./inst mkdir "$DBDATA" 755 || exit 1
- X
- X if $NNTP ; then
- X if [ x"$NNTPCACHE" != "x" ] ; then
- X ./inst mkdir "$NNTPCACHE" 777 || exit 1
- X fi
- X ILIMIT=50
- X DFLT=50
- X
- X cat <<'EOF'
- X
- XWhen nnmaster is started the first time after initializing nn's
- Xdatabase, it will attempt to fetch all the articles from the nntp
- Xserver. It does this by successively requesting each article in the
- Xrange min..last obtained from the NNTP server. Often the 'min' number
- Xis unreliable or even zero (Cnews doesn't maintain it). This means
- Xthat the nnmaster will request a lot of non-existing articles from the
- Xserver, causing a lot of network traffic.
- X
- XTo limit this activity, nn will normally only attempt to fetch the
- Xfifty newest articles in each group. This shouldn't really be a
- Xproblem since that will give you enough news to start with, and the
- Xolder articles will probably be expired in a few days anyway.
- X
- XYou can change this limit if you like. Or you can disable this
- Xlimitation completely if you trust the min field by giving a 0 limit.
- X
- XEOF
- X else
- X ILIMIT=""
- X DFLT="none"
- X
- X cat <<'EOF'
- X
- XIf the 'min' field in your active file is not reliable, nnmaster can
- Xwaste a lot of time trying to locate non-existing articles in the news
- Xgroups when it is collecting the available articles the first time it
- Xis started after the database is initialized. This is especially true
- Xwith Cnews where the min field is not normally maintained.
- X
- XTo limit the efforts during the initial collection, you can set a
- Xlimit on the number of articles in each group which nnmaster should
- Xtry to locate in each group. This may get you running faster, and it
- Xshouldn't matter much anyway since the articles that may be ignored
- Xwill be the oldest articles in the group, and they will probably be
- Xexpired soon anyway. A value in the range 100-500 should be more than
- Xenough. If you don't specify a limit, all articles will be collected,
- Xbut it may take quite some time if the min fields are unreliable.
- XEOF
- X fi
- X
- X ${AWK} 'END{printf "Initial article limit ('"$DFLT"') "}' < /dev/null
- X read L
- X if [ -n "$L" ] ; then
- X ILIMIT="$L"
- X fi
- X
- X echo Running nnmaster -I $ILIMIT to initialize database....
- X echo
- X $MASTER/nnmaster -I $ILIMIT
- X echo
- X echo "Now start $MASTER/nnmaster [ -D ] [ -r ]"
- X ;;
- Xesac
- X
- Xdone
- X
- Xif [ -f $LOG ]
- Xthen
- X chmod 666 $LOG
- Xfi
- X
- Xif $PAUSE
- Xthen
- X${AWK} 'BEGIN{printf("\nHit return to continue....")}' < /dev/null
- Xread X
- Xfi
- Xdone
- END_OF_FILE
- if test 7589 -ne `wc -c <'inst.sh'`; then
- echo shar: \"'inst.sh'\" unpacked with wrong size!
- fi
- # end of 'inst.sh'
- fi
- if test -f 'news.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'news.c'\"
- else
- echo shar: Extracting \"'news.c'\" \(6563 characters\)
- sed "s/^X//" >'news.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- X *
- X * Article header parsing.
- X */
- X
- X#include "config.h"
- X#include "news.h"
- X
- Xexport retry_on_error = 0;
- X
- Xchar *parse_header(f, hdr_field, modes, hdrbuf)
- XFILE *f;
- Xchar **(*hdr_field)();
- Xint modes;
- Xnews_header_buffer hdrbuf;
- X{
- X register char *bp, *cp, **fptr;
- X int siz, all, date_only;
- X off_t pos;
- X
- X pos = ftell(f);
- X
- X/* read first NEWS_HEADER_BUFFER bytes (should be more than enough) */
- X
- X all = modes & GET_ALL_FIELDS;
- X date_only = modes & GET_DATE_ONLY;
- X
- X siz = fread(hdrbuf, sizeof(char), NEWS_HEADER_BUFFER, f);
- X
- X bp = hdrbuf;
- X bp[siz-1] = NUL;
- X
- X /* decode subarticle header */
- X while (*bp) {
- X
- X if (*bp == NL) { /* empty line following header */
- X ++bp;
- X fseek(f, pos + (bp - hdrbuf), 0);
- X return bp;
- X }
- X
- X if (*bp == SP) { /* for comp.ai.neural-nets digests */
- X bp++; /* which have <NL><space><NL> after header */
- X continue;
- X }
- X
- X if (date_only && *bp != 'D')
- X fptr = NULL;
- X else
- X if (fptr = (*hdr_field)(bp, all)) {
- X while (*bp && *bp != ':' && isascii(*bp) && !isspace(*bp))
- X bp++;
- X bp++;
- X while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++;
- X *fptr = bp;
- X }
- X
- X while (*bp && *bp != NL) bp++;
- X
- X /* Assume that continued lines are never empty! */
- X if (fptr && bp == *fptr) *fptr = NULL;
- X
- X while (*bp) { /* look for continued lines */
- X cp = bp + 1;
- X while (*cp && isascii(*cp) && isspace(*cp) && *cp != NL) cp++;
- X
- X if (cp == bp + 1) {
- X /* next line is empty or not indented */
- X *bp++ = NUL;
- X break;
- X }
- X
- X if (*cp == NUL || *cp == NL) {
- X /* next line is not empty, but blank line */
- X *bp = NUL;
- X bp = cp; /* assume end of header */
- X break;
- X }
- X
- X *bp = SP; /* substitute NL with SPACE */
- X bp = cp;
- X while (*bp && *bp != NL) bp++;
- X }
- X }
- X
- X return bp;
- X}
- X
- Xstatic char **art_hdr_field(lp, all)
- Xregister char *lp;
- Xint all;
- X{
- X
- X#define check(name, lgt, field) \
- X if (isascii(lp[lgt]) && isspace(lp[lgt]) && strncmp(name, lp, lgt) == 0)\
- X return &news.field
- X
- X switch (*lp++) {
- X
- X case 'A':
- X case 'a':
- X if (!all) break;
- X check("pproved:", 8, ng_appr);
- X break;
- X
- X case 'B':
- X case 'b':
- X check("ack-References:", 15, ng_bref);
- X break;
- X
- X case 'D':
- X case 'd':
- X check("ate:", 4, ng_date);
- X if (!all) break;
- X check("ate-Received:", 13, ng_rdate);
- X check("istribution:", 12, ng_dist);
- X break;
- X
- X case 'F':
- X case 'f':
- X check("rom:", 4, ng_from);
- X if (!all) break;
- X check("ollowup-To:", 11, ng_follow);
- X check("ollowup-to:", 11, ng_follow);
- X break;
- X
- X case 'K':
- X case 'k':
- X if (!all) break;
- X check("eywords:", 8, ng_keyw);
- X break;
- X
- X case 'L':
- X case 'l':
- X check("ines:", 5, ng_xlines);
- X break;
- X
- X case 'M':
- X case 'm':
- X if (!all) break;
- X if (strncmp(lp, "essage-", 7)) break;
- X lp += 7;
- X check("ID:", 3, ng_ident);
- X check("Id:", 3, ng_ident);
- X check("id:", 3, ng_ident);
- X break;
- X
- X case 'N':
- X case 'n':
- X check("ewsgroups:", 10, ng_groups);
- X break;
- X
- X case 'O':
- X case 'o':
- X if (!all) break;
- X check("rganization:", 12, ng_org);
- X check("rganisation:", 12, ng_org);
- X break;
- X
- X case 'P':
- X case 'p':
- X if (!all) break;
- X check("ath:", 4, ng_path);
- X break;
- X
- X case 'R':
- X case 'r':
- X check("eferences:", 10, ng_ref);
- X check("eply-To:", 8, ng_reply);
- X check("eply-to:", 8, ng_reply);
- X break;
- X
- X case 'S':
- X case 's':
- X check("ubject:", 7, ng_subj);
- X if (news.ng_from == NULL)
- X check("ender:", 6, ng_from);
- X if (!all) break;
- X check("ummary:", 7, ng_summ);
- X break;
- X
- X case 'T':
- X case 't':
- X check("itle:", 5, ng_subj);
- X break;
- X }
- X
- X return NULL;
- X
- X#undef check
- X}
- X
- Xis_header_line(line)
- Xchar *line;
- X{
- X return art_hdr_field(line, 0) != (char **)NULL;
- X}
- X
- X
- XFILE *open_news_article(art, modes, buffer1, buffer2)
- Xarticle_header *art;
- Xint modes;
- Xnews_header_buffer buffer1, buffer2;
- X{
- X char *body;
- X char *digest_buffer;
- X char *parse_header();
- X struct stat statb;
- X int retry;
- X FILE *f;
- X#ifdef NNTP
- X int lazy;
- X FILE *nntp_get_article();
- X#endif /* NNTP */
- X
- X if (art->flag & A_FOLDER) {
- X f = open_file(group_path_name, OPEN_READ);
- X if (f == NULL) return NULL;
- X fseek(f, art->hpos, 0);
- X#ifdef NNTP
- X } else
- X if (use_nntp) {
- X lazy = (current_group->master_flag & M_ALWAYS_DIGEST) == 0
- X && (modes & LAZY_BODY) ? 1 : 0;
- X f = nntp_get_article(art->a_number, lazy);
- X if (f == NULL) return NULL;
- X#endif /* NNTP */
- X } else {
- X sprintf(group_file_name, "%d", art->a_number);
- X
- X retry = retry_on_error;
- X while ((f = open_file(group_path_name, OPEN_READ)) == NULL)
- X if (--retry < 0) return NULL;
- X
- X /* necessary because empty files wreak havoc */
- X if (fstat(fileno(f), &statb) < 0 ||
- X statb.st_size < art->lpos || statb.st_size <= (off_t)0) {
- X fclose(f);
- X return who_am_i == I_AM_MASTER ? (FILE *)1 : NULL;
- X }
- X }
- X
- X digest_buffer = buffer1;
- X
- X if (modes & FILL_NEWS_HEADER) {
- X
- X news.ng_from = NULL;
- X news.ng_reply = NULL;
- X news.ng_name = NULL;
- X news.ng_subj = NULL;
- X news.ng_groups = NULL;
- X news.ng_ref = NULL;
- X news.ng_bref = NULL;
- X
- X news.ng_xlines = NULL;
- X
- X if (modes & GET_ALL_FIELDS) {
- X news.ng_path = NULL;
- X news.ng_reply = NULL;
- X news.ng_ident = NULL;
- X news.ng_follow = NULL;
- X news.ng_keyw = NULL;
- X news.ng_dist = NULL;
- X news.ng_org = NULL;
- X news.ng_appr = NULL;
- X news.ng_summ = NULL;
- X news.ng_date = NULL;
- X news.ng_rdate = NULL;
- X }
- X
- X if (modes & GET_DATE_ONLY)
- X news.ng_date = NULL;
- X
- X body = parse_header(f, art_hdr_field, modes, buffer1);
- X
- X news.ng_lines = news.ng_xlines ? atoi(news.ng_xlines) : -1;
- X
- X if (modes & FILL_OFFSETS) {
- X art->fpos = news.ng_fpos = ftell(f);
- X
- X fseek(f, (off_t)0, 2);
- X news.ng_lpos = ftell(f);
- X }
- X#ifdef NNTP
- X else if (use_nntp && (art->flag & A_DIGEST) == 0) {
- X fseek(f, (off_t)0, 2);
- X art->lpos = ftell(f);
- X }
- X#endif
- X
- X news.ng_flag = 0;
- X
- X if (news.ng_appr) news.ng_flag |= N_MODERATED;
- X
- X if (modes & DIGEST_CHECK && is_digest()) news.ng_flag |= N_DIGEST;
- X
- X#ifdef NNTP
- X if (use_nntp && lazy && news.ng_flag & N_DIGEST) {
- X fclose(f);
- X f = nntp_get_article(art->a_number, 2);
- X if (f == NULL) return NULL;
- X }
- X#endif
- X digest_buffer = buffer2;
- X }
- X#ifdef NNTP
- X else if (use_nntp && (art->flag & A_DIGEST) == 0) {
- X fseek(f, (off_t)0, 2);
- X art->lpos = ftell(f);
- X }
- X#endif
- X
- X if (modes & FILL_DIGEST_HEADER) {
- X fseek(f, art->hpos, 0);
- X parse_digest_header(f, modes & GET_ALL_FIELDS, digest_buffer);
- X }
- X
- X fseek(f, (modes & SKIP_HEADER) ? art->fpos : art->hpos, 0);
- X
- X return f;
- X}
- END_OF_FILE
- if test 6563 -ne `wc -c <'news.c'`; then
- echo shar: \"'news.c'\" unpacked with wrong size!
- fi
- # end of 'news.c'
- fi
- if test -f 'reroute.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'reroute.c'\"
- else
- echo shar: Extracting \"'reroute.c'\" \(7348 characters\)
- sed "s/^X//" >'reroute.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- X *
- X * Reply address rewriting.
- X */
- X
- X#include "config.h"
- X
- X#define TRACE
- X
- X
- X#ifdef HAVE_ROUTING
- X
- Xreroute(route, address)
- Xchar *route, *address;
- X{
- X char *name, *atpos;
- X register char *sp;
- X register c;
- X
- X if (atpos = strchr(address, '@')) {
- X name = atpos;
- X
- X while (--name >= address)
- X if (isspace(*name) || *name == '<') {
- X name++;
- X break;
- X }
- X if (name < address) name++;
- X
- X for (sp = atpos; c = *sp; sp++)
- X if (isspace(c) || c == '>') break;
- X
- X *sp = NUL;
- X strcpy(route, name);
- X *sp = c;
- X } else
- X strcpy(route, address);
- X return 1;
- X}
- X
- X#else
- X
- X
- X#ifdef TRACE
- XFILE *route_trace = NULL;
- X#endif
- Xstatic char cmdc; /* we need this for trace output */
- X
- X
- Xstatic char *cstreq(string, match)
- Xchar *string, *match;
- X{
- X register char *s1, *s2;
- X s1 = string;
- X
- Xnext_part:
- X s2 = match;
- X
- X while (isspace(*s1) || *s1 == ',') s1++;
- X
- X while (*s2) {
- X if (*s1 == NUL || isspace(*s1)) return NULL;
- X if (*s1 == ',') goto next_part;
- X if (toupper(*s1) != toupper(*s2)) break;
- X s1++, s2++;
- X }
- X
- X if (*s2 == NUL && (*s1 == NUL || isspace(*s1) || *s1 == ',')) {
- X if (*s1 == ',') while (*s1 && !isspace(*s1)) s1++;
- X#ifdef TRACE
- X if (route_trace)
- X fprintf(route_trace, "/%c %s=%s -> %s", cmdc, string, match, s1);
- X#endif
- X return s1;
- X }
- X
- X while (*s1 && !isspace(*s1)) {
- X if (*s1 == ',') goto next_part;
- X s1++;
- X }
- X
- X return NULL;
- X}
- X
- X
- Xstatic char *cstrcpy(s1, s2)
- Xregister char *s1, *s2;
- X{
- X while (*s2 && isspace(*s2)) s2++;
- X while (*s2 && !isspace(*s2) && *s2 != ',') *s1++ = *s2++;
- X *s1 = NUL;
- X return s1;
- X}
- X
- X/*
- X * lookup site,domain in routes database
- X * if not found and bang is non-empty, use bang default if it exist
- X */
- X
- Xstatic find_route(route, remote_user, remote_host, remote_domain, bang)
- Xchar *route, *remote_user, *remote_host, *remote_domain, *bang;
- X{
- X char line[512]; /* line from route file */
- X register char *lp; /* current line position */
- X char *routep; /* ptr into route */
- X char *pattern; /* pattern from line */
- X int dom_ok; /* in right domain */
- X int host_ok; /* right host */
- X FILE *rf; /* route file */
- X char local_host[100]; /* callers host name */
- X char local_domain[100]; /* this domain */
- X
- X if (bang && *bang == NUL) bang = NULL;
- X if (remote_host == NULL || *remote_host == NUL) return 0;
- X
- X if (remote_domain && *remote_domain == NUL) remote_domain = NULL;
- X
- X gethostname(local_host, 100);
- X if (routep = strchr(local_host, '.')) *routep = NUL;
- X local_domain[0] = NUL;
- X
- X rf = open_file(relative(lib_directory, "routes"), OPEN_READ);
- X if (rf == NULL) {
- X#ifdef TRACE
- X if (route_trace) fprintf(route_trace, "---No routes file\n");
- X#endif
- X return 0;
- X }
- X
- X dom_ok = host_ok = 1;
- X routep = route;
- X pattern = NULL;
- X
- X while (fgets(line, 512, rf) != NULL) {
- X lp = line;
- X while (*lp && isspace(*lp)) lp++;
- X if (*lp == NUL || *lp == '#') continue;
- X
- X if (*lp == '/') {
- X lp++;
- X cmdc = *lp++;
- X while (*lp && isspace(*lp)) lp++;
- X if (*lp == '#') *lp = NUL;
- X
- X if (cmdc == 'L') { /* local (default) domain name(s) */
- X cstrcpy(local_domain, lp);
- X
- X if (remote_domain == NULL ||
- X cstreq(lp, remote_domain) != NULL) {
- X dom_ok = 1;
- X if (strcmp(local_host, remote_host) == 0) {
- X pattern = "%p%n";
- X break;
- X }
- X }
- X continue;
- X }
- X
- X if (cmdc == 'D') { /* destination domain */
- X if (*lp == NUL)
- X dom_ok = 1;
- X else
- X dom_ok = (cstreq(lp, remote_domain) != NULL);
- X continue;
- X }
- X
- X if (!dom_ok) continue;
- X
- X if (cmdc == 'H') { /* local host */
- X if (*lp == NUL)
- X host_ok = 1;
- X else
- X host_ok = (cstreq(lp, local_host) != NULL);
- X continue;
- X }
- X
- X if (!host_ok) continue;
- X
- X switch (cmdc) {
- X
- X case 'N': /* neighbouring (uucp) sites */
- X if (cstreq(lp, remote_host) == NULL) continue;
- X pattern = "%s!%n";
- X break;
- X
- X case 'P':
- X if (*lp == '+')
- X routep = cstrcpy(routep, ++lp);
- X else
- X routep = cstrcpy(route, lp);
- X continue;
- X
- X case 'G':
- X pattern = lp;
- X break;
- X
- X case 'B':
- X if (!bang) continue;
- X pattern = lp;
- X break;
- X
- X default:
- X continue;
- X }
- X
- X break;
- X }
- X
- X if (!dom_ok) continue;
- X if (!host_ok) continue;
- X
- X if ((pattern = cstreq(lp, remote_host))!=NULL) break;
- X }
- X
- X fclose(rf);
- X
- X if (pattern == NULL) return 0;
- X
- X#ifdef TRACE
- X if (route_trace) fprintf(route_trace, " pattern='%s'\n", pattern);
- X#endif
- X
- X for (; *pattern != NL && *pattern != NUL; pattern++) {
- X if (*pattern == SP || *pattern == TAB) continue;
- X if (*pattern == '%') {
- X pattern++;
- X switch(*pattern) {
- X case 'n':
- X routep = cstrcpy(routep, remote_user);
- X continue;
- X case 's':
- X routep = cstrcpy(routep, remote_host);
- X continue;
- X case 'd':
- X routep = cstrcpy(routep,
- X remote_domain ? remote_domain : local_domain);
- X continue;
- X case 'b':
- X routep = cstrcpy(routep, bang);
- X continue;
- X case 'p':
- X routep = route;
- X continue;
- X case '%':
- X break;
- X default:
- X continue;
- X }
- X }
- X *routep++ = *pattern;
- X }
- X *routep = NUL;
- X
- X return 1;
- X}
- X
- Xreroute(route, address)
- Xchar *route, *address;
- X{
- X char *name, *site, *domain;
- X char *atpos, *dotpos;
- X register char *sp;
- X register c;
- X int found;
- X
- X#ifdef TRACE
- X if (route_trace ||
- X (route_trace = open_file(relative(nn_directory, "trace"),
- X OPEN_APPEND | DONT_CREATE)))
- X fprintf(route_trace, "--orig: '%s'\n", address);
- X#endif
- X
- X found = 0;
- X
- X /* if a sender (or receiver!) is not provided,
- X * we first try the site from the 'Reply-To:'
- X * and 'From:' lines who@site.domain */
- X
- X if (atpos = strchr(address, '@')) {
- X *atpos = NUL;
- X name = atpos;
- X
- X while (--name >= address)
- X if (isspace(*name) || *name == '<') {
- X name++;
- X break;
- X }
- X if (name < address) name++;
- X
- X dotpos = atpos;
- X site = atpos + 1;
- X
- X next_dot:
- X *dotpos = NUL;
- X domain = dotpos + 1;
- X for (sp = domain; c = *sp; sp++) {
- X if (isspace(c) || c == '>') break;
- X if (c == '.') {
- X *dotpos = '.';
- X dotpos = sp;
- X goto next_dot;
- X }
- X }
- X *sp = NUL;
- X if (site == domain)
- X domain = NULL;
- X else
- X *atpos = NUL; /* overwritten when first . is found */
- X
- X#ifdef TRACE
- X if (route_trace)
- X fprintf(route_trace,
- X " @-type: name='%s' site='%s' domain='%s'\n",
- X name, site, domain ? domain : "");
- X#endif
- X
- X found = find_route(route, name, site, domain, (char *)NULL);
- X
- X if (dotpos) { *dotpos = '.'; *sp = c; }
- X if (atpos) *atpos = '@';
- X
- X goto out;
- X }
- X
- X /*
- X * not domain address -- look for bang address
- X */
- X
- X if (!(name = strrchr(address, '!'))) {
- X /*
- X * neither domain nor bang -- suppose it is a local address
- X */
- X strcpy(route, address);
- X found = 1;
- X goto out;
- X }
- X
- X *name++ = NUL;
- X if (site = strrchr(address, '!'))
- X *site++ = NUL;
- X else {
- X site = address;
- X address = NULL;
- X }
- X
- X#ifdef TRACE
- X if (route_trace)
- X fprintf(route_trace,
- X " !-type: name='%s' site='%s' bang='%s'\n",
- X name, site, address ? address : "NONE");
- X#endif
- X
- X found = find_route(route, name, site, (char *)NULL, address);
- X
- X *--name = '!';
- X if (address) *--site = '!';
- X
- X out:
- X
- X#ifdef TRACE
- X if (route_trace) {
- X if (found)
- X fprintf(route_trace, "--route='%s'\n\n", route);
- X else
- X fprintf(route_trace, "--NO ROUTE\n\n");
- X fclose(route_trace);
- X route_trace = NULL;
- X }
- X#endif
- X return found;
- X}
- X
- X#endif
- END_OF_FILE
- if test 7348 -ne `wc -c <'reroute.c'`; then
- echo shar: \"'reroute.c'\" unpacked with wrong size!
- fi
- # end of 'reroute.c'
- fi
- if test -f 'unshar.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unshar.c'\"
- else
- echo shar: Extracting \"'unshar.c'\" \(5341 characters\)
- sed "s/^X//" >'unshar.c' <<'END_OF_FILE'
- X/****************************************************************
- X * unshar.c: Unpackage one or more shell archive files
- X *
- X * Description: unshar is a filter which removes the front part
- X * of a file and passes the rest to the 'sh' command.
- X * It understands phrases like "cut here", and also
- X * knows about shell comment characters and the Unix
- X * commands "echo", "cat", and "sed".
- X *
- X * HISTORY
- X * 27-July-88 Kim F. Storm (storm@texas.dk) Texas Instruments, Denmark
- X * Adapted to :unshar command in nn
- X * Added static to function declarations
- X * Removed all unused functions, i.e. not useful as stand-alone pgm.
- X * 29-Jan-85 Michael Mauldin (mlm) at Carnegie-Mellon University
- X * Created.
- X ****************************************************************/
- X
- X#include "config.h"
- X
- X
- X/*****************************************************************
- X * stlmatch -- match leftmost part of string
- X *
- X * Usage: i = stlmatch (big,small)
- X * int i;
- X * char *small, *big;
- X *
- X * Returns 1 iff initial characters of big match small exactly;
- X * else 0.
- X *
- X * HISTORY
- X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
- X * Ripped out of CMU lib for Rog-O-Matic portability
- X * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
- X * Rewritten for VAX from Ken Greer's routine.
- X *
- X * Originally from klg (Ken Greer) on IUS/SUS UNIX
- X *****************************************************************/
- X
- Xstatic int stlmatch (big, small)
- Xchar *small, *big;
- X{ register char *s, *b;
- X s = small;
- X b = big;
- X do
- X { if (*s == '\0')
- X return (1);
- X }
- X while (*s++ == *b++);
- X return (0);
- X}
- X
- X/*****************************************************************
- X * smatch: Given a data string and a pattern containing one or
- X * more embedded stars (*) (which match any number of characters)
- X * return true if the match succeeds, and set res[i] to the
- X * characters matched by the 'i'th *.
- X *****************************************************************/
- X
- Xstatic smatch (dat, pat, res)
- Xregister char *dat, *pat, **res;
- X{ register char *star = 0, *starend, *resp;
- X int nres = 0;
- X
- X while (1)
- X { if (*pat == '*')
- X { star = ++pat; /* Pattern after * */
- X starend = dat; /* Data after * match */
- X resp = res[nres++]; /* Result string */
- X *resp = '\0'; /* Initially null */
- X }
- X else if (*dat == *pat) /* Characters match */
- X { if (*pat == '\0') /* Pattern matches */
- X return (1);
- X pat++; /* Try next position */
- X dat++;
- X }
- X else
- X { if (*dat == '\0') /* Pattern fails - no more */
- X return (0); /* data */
- X if (star == 0) /* Pattern fails - no * to */
- X return (0); /* adjust */
- X pat = star; /* Restart pattern after * */
- X *resp++ = *starend; /* Copy character to result */
- X *resp = '\0'; /* null terminate */
- X dat = ++starend; /* Rescan after copied char */
- X }
- X }
- X}
- X
- X/****************************************************************
- X * position: position 'fil' at the start of the shell command
- X * portion of a shell archive file.
- X * Kim Storm: removed static variables
- X ****************************************************************/
- X
- Xunshar_position (fil)
- XFILE *fil;
- X{
- X char buf[BUFSIZ];
- X long pos, ftell ();
- X
- X /* Results from star matcher */
- X char res1[BUFSIZ], res2[BUFSIZ], res3[BUFSIZ], res4[BUFSIZ];
- X char *result[4];
- X
- X result[0] = res1, result[1] = res2, result[2] = res3, result[3] = res4 ;
- X
- X /* rewind (fil); */
- X
- X while (1) {
- X /* Record position of the start of this line */
- X pos = ftell (fil);
- X
- X /* Read next line, fail if no more */
- X if (fgets (buf, BUFSIZ, fil) == NULL) {
- X msg("no shell commands in file");
- X return (0);
- X }
- X
- X /* Bail out if we see C preprocessor commands or C comments */
- X if (stlmatch (buf, "#include") || stlmatch (buf, "# include") ||
- X stlmatch (buf, "#define") || stlmatch (buf, "# define") ||
- X stlmatch (buf, "#ifdef") || stlmatch (buf, "# ifdef") ||
- X stlmatch (buf, "#ifndef") || stlmatch (buf, "# ifndef") ||
- X stlmatch (buf, "/*"))
- X {
- X msg("file looks like raw C code, not a shar file");
- X return (0);
- X }
- X
- X /* Does this line start with a shell command or comment */
- X if (stlmatch (buf, "#") ||
- X stlmatch (buf, ":") ||
- X stlmatch (buf, "echo ") ||
- X stlmatch (buf, "sed ") ||
- X stlmatch (buf, "cat "))
- X {
- X fseek (fil, pos, 0);
- X return (1);
- X }
- X
- X /* Does this line say "Cut here" */
- X if (smatch (buf, "*CUT*HERE*", result) ||
- X smatch (buf, "*cut*here*", result) ||
- X smatch (buf, "*TEAR*HERE*", result) ||
- X smatch (buf, "*tear*here*", result) ||
- X smatch (buf, "*CUT*CUT*", result) ||
- X smatch (buf, "*cut*cut*", result))
- X {
- X /* Read next line after "cut here", skipping blank lines */
- X while (1) {
- X pos = ftell (fil);
- X
- X if (fgets (buf, BUFSIZ, fil) == NULL) {
- X msg("no shell commands after 'cut'");
- X return (0);
- X }
- X
- X if (*buf != '\n') break;
- X }
- X
- X /*
- X * Win if line starts with a comment character of
- X * lower case letter
- X */
- X if (*buf == '#' ||
- X *buf == ':' ||
- X (('a' <= *buf) && ('z' >= *buf))) {
- X fseek (fil, pos, 0);
- X return (1);
- X }
- X
- X /* Cut here message lied to us */
- X msg("invalid data after CUT line");
- X return (0);
- X }
- X }
- X}
- X
- END_OF_FILE
- if test 5341 -ne `wc -c <'unshar.c'`; then
- echo shar: \"'unshar.c'\" unpacked with wrong size!
- fi
- # end of 'unshar.c'
- fi
- if test -f 'xmakefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xmakefile'\"
- else
- echo shar: Extracting \"'xmakefile'\" \(6903 characters\)
- sed "s/^X//" >'xmakefile' <<'END_OF_FILE'
- X*
- X* DO NOT CHANGE THIS MAKEFILE DIRECTLY
- X*
- X* THERE ARE NO CONFIGURATION PARAMETERS IN THIS FILE
- X*
- X
- X#include "config.h"
- X#undef global
- X#undef SHELL
- X
- X#ifndef COMPILER_FLAGS
- X#define COMPILER_FLAGS
- X#endif
- X
- X#ifndef EXTRA_LIB
- X#define EXTRA_LIB
- X#endif
- X
- X#ifdef HAVE_ROUTING
- X#define NNMAIL
- X#else
- X#define NNMAIL nnmail
- X#endif
- X
- X#ifdef ACCOUNTING
- X#define ACCOUNT nnacct
- X#else
- X#ifdef AUTHORIZE
- X#define ACCOUNT nnacct
- X#else
- X#define ACCOUNT
- X#endif
- X#endif
- X------------------ MAKE WILL CUT HERE -------------
- X*
- X* Notice: ymakefile is made from xmakefile by the Makefile.
- X*
- X
- XCC = COMPILER
- XCPP = PREPROC
- XCFLAGS = -Iconf COMPILER_FLAGS CDEBUG
- X
- X*
- X* Resulting programs
- X*
- X
- XBIN_PROG = nn NNMAIL nnusage nngrab nnstats ACCOUNT
- XBIN_LINK = nncheck nnadmin nntidy nngoback nngrep nnpost
- XLIB_PROG = aux upgrade_rc
- XMASTER_PROG = nnmaster back_act nnspew
- X
- X*
- X* Compilation
- X*
- X
- XSHELL = /bin/sh
- X
- XMASTER = master.o collect.o expire.o proto.o \
- X global.o options.o active.o db.o nntp.o \
- X pack_date.o pack_name.o pack_subject.o news.o digest.o
- X
- XNN = nn.o admin.o proto.o global.o options.o db.o nntp.o \
- X init.o variable.o term.o keymap.o macro.o regexp.o \
- X menu.o more.o newsrc.o group.o folder.o dir.o \
- X sort.o articles.o sequence.o kill.o active.o fullname.o \
- X answer.o reroute.o hostname.o save.o unshar.o decode.o execute.o \
- X pack_date.o pack_name.o pack_subject.o news.o digest.o match.o
- X
- XACCT = account.o global.o options.o proto.o
- X
- XMAIL = nnmail.o reroute.o hostname.o global.o options.o
- X
- X
- Xall: $(BIN_PROG) $(LIB_PROG) $(MASTER_PROG) inst
- X
- Xclient: $(BIN_PROG) $(LIB_PROG) inst
- X
- Xmaster: $(MASTER_PROG) inst
- X
- Xnn: $(NN)
- X @echo linking nn
- X @$(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -o nn
- X
- Xnnmaster: $(MASTER)
- X @echo linking nnmaster
- X @$(CC) $(CFLAGS) $(MASTER) EXTRA_LIB -o nnmaster
- X
- Xnnmail: $(MAIL)
- X @echo linking nnmail
- X @$(CC) $(CFLAGS) $(MAIL) EXTRA_LIB -o nnmail
- X
- Xnnstats: nnstats.sh prefix
- X cat prefix nnstats.sh > nnstats ; chmod +x nnstats
- X
- Xnnusage: nnusage.sh prefix
- X cat prefix nnusage.sh > nnusage ; chmod +x nnusage
- X
- Xnngrab: nngrab.sh prefix
- X cat prefix nngrab.sh > nngrab ; chmod +x nngrab
- X
- Xaux: aux.sh prefix
- X cat prefix aux.sh > aux ; chmod +x aux
- X
- Xupgrade_rc: upgrade_rc.sh prefix
- X cat prefix upgrade_rc.sh > upgrade_rc ; chmod +x upgrade_rc
- X
- Xnnacct: $(ACCT)
- X @echo linking nnacct
- X @$(CC) $(CFLAGS) $(ACCT) EXTRA_LIB -o nnacct
- X
- Xback_act: back_act.sh prefix
- X cat prefix back_act.sh > back_act ; chmod +x back_act
- X
- Xnnspew: nnspew.sh prefix
- X cat prefix nnspew.sh > nnspew ; chmod +x nnspew
- X
- Xprefix: config.h mkprefix
- X ./mkprefix prefix < /dev/null > prefix
- X
- Xmkprefix: prefix.o global.o
- X $(CC) $(CFLAGS) prefix.o global.o EXTRA_LIB -o mkprefix
- X
- X*
- X* Configuration counter updating
- X*
- X
- Xupdate.h: config.h patchlevel.h Makefile
- X @sh -c "[ -f update.h ] || (echo 0 > update.h)"
- X @sh -c "expr `cat update.h` + 1 > update1.h && mv update1.h update.h"
- X @echo configuration number updated to `cat update.h`
- X
- X*
- X* Installation
- X*
- X
- Xcvt-help: cvt-help.c
- X $(CC) -o cvt-help cvt-help.c
- X
- Xusercheck: usercheck.c
- X $(CC) -o usercheck usercheck.c
- X
- Xinst: config.h xmakefile inst.sh cvt-help usercheck mkprefix man/nn.1
- X @echo building install script: ./inst
- X @./mkprefix full < /dev/null > inst
- X @echo BIN_PROG=\"$(BIN_PROG)\" >> inst
- X @echo BIN_LINK=\"$(BIN_LINK)\" >> inst
- X @echo LIB_PROG=\"$(LIB_PROG)\" >> inst
- X @echo MASTER_PROG=\"$(MASTER_PROG)\" >> inst
- X @cat inst.sh >> inst
- X @chmod 755 inst
- X
- X* merge nn.1
- X
- Xman/nn.1: man/nn.1.A man/nn.1.B man/nn.1.C man/nn.1.D
- X [ ! -f man/nn.1 ] || mv man/nn.1 man/nn.1~
- X cat man/nn.1.? > man/nn.1
- X
- X*
- X* Clean -- remove compiled programs
- X*
- X
- Xclean:
- X rm -f $(BIN_PROG) $(LIB_PROG) $(MASTER_PROG) cvt-help usercheck
- X
- X*
- X* dependencies
- X*
- X
- Xaccount.o: account.c config.h global.h vararg.h options.h proto.h
- Xactive.o: active.c config.h global.h vararg.h data.h
- Xadmin.o: admin.c config.h global.h vararg.h data.h db.h term.h \
- X proto.h
- Xanswer.o: answer.c config.h global.h vararg.h data.h news.h term.h \
- X keymap.h options.h
- Xarticles.o: articles.c config.h global.h vararg.h data.h db.h articles.h
- Xcollect.o: collect.c config.h global.h vararg.h data.h db.h news.h
- Xdb.o: db.c config.h global.h vararg.h data.h db.h
- Xdecode.o: decode.c config.h global.h vararg.h data.h
- Xdigest.o: digest.c config.h global.h vararg.h data.h news.h debug.h
- Xdir.o: dir.c config.h global.h vararg.h data.h articles.h dir.h
- Xexecute.o: execute.c config.h global.h vararg.h data.h term.h
- Xexpire.o: expire.c config.h global.h vararg.h data.h db.h dir.h
- Xfolder.o: folder.c config.h global.h vararg.h data.h articles.h news.h \
- X term.h menu.h
- Xfullname.o: fullname.c config.h global.h
- Xglobal.o: global.c config.h global.h vararg.h data.h \
- X patchlevel.h update.h
- Xgroup.o: group.c config.h global.h vararg.h data.h articles.h db.h \
- X term.h menu.h keymap.h regexp.h
- Xhostname.o: hostname.c config.h
- Xinit.o: init.c config.h global.h vararg.h data.h articles.h term.h \
- X keymap.h menu.h
- Xkeymap.o: keymap.c config.h global.h vararg.h data.h keymap.h term.h
- Xkill.o: kill.c config.h global.h vararg.h data.h term.h regexp.h
- Xmacro.o: macro.c config.h global.h vararg.h data.h keymap.h term.h
- Xmaster.o: master.c config.h global.h vararg.h data.h db.h \
- X options.h proto.h
- Xmatch.o: match.c config.h global.h regexp.h
- Xmenu.o: menu.c config.h global.h vararg.h data.h articles.h term.h \
- X keymap.h menu.h regexp.h
- Xmore.o: more.c config.h global.h vararg.h data.h news.h term.h \
- X menu.h keymap.h regexp.h
- Xnews.o: news.c config.h global.h vararg.h data.h news.h
- Xnn.o: nn.c config.h global.h vararg.h data.h menu.h term.h \
- X keymap.h options.h articles.h proto.h
- Xnnmail.o: nnmail.c config.h global.h vararg.h data.h options.h
- Xnntp.o: nntp.c config.h global.h vararg.h data.h nntp.h
- Xoptions.o: options.c config.h global.h vararg.h data.h options.h
- Xpack_date.o: pack_date.c config.h global.h vararg.h data.h
- Xpack_name.o: pack_name.c config.h global.h vararg.h data.h
- Xpack_subject.o: pack_subject.c config.h global.h vararg.h data.h
- Xprefix.o: config.h global.h
- Xproto.o: proto.c config.h global.h proto.h
- Xnewsrc.o: newsrc.c config.h global.h vararg.h data.h term.h debug.h
- Xregexp.o: regexp.c config.h global.h vararg.h data.h regexp.h
- Xreroute.o: reroute.c config.h global.h vararg.h data.h
- Xsave.o: save.c config.h global.h vararg.h data.h term.h keymap.h \
- X news.h
- Xselection.o: selection.c config.h global.h vararg.h data.h term.h\
- X articles.h
- Xsequence.o: sequence.c config.h global.h vararg.h data.h debug.h
- Xsort.o: sort.c config.h global.h vararg.h data.h
- Xterm.o: term.c config.h global.h vararg.h data.h term.h keymap.h
- Xunshar.o: unshar.c config.h global.h vararg.h data.h
- Xvariable.o: variable.c config.h global.h vararg.h data.h
- X
- X* link debugging version
- X
- Xnn1: $(NN)
- X $(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -Mnn1 -o nn1
- X
- Xnnmaster1: $(MASTER)
- X $(CC) $(CFLAGS) $(MASTER) EXTRA_LIB -Mnnmaster1 -o nnmaster1
- X
- Xlint:
- X echo LINTING NN
- X* lint -Iconf -u -DNNTP $(NN:.o=.c)
- X echo LINTING MASTER
- X* lint -Iconf -u -DNNTP $(MASTER:.o=.c)
- END_OF_FILE
- if test 6903 -ne `wc -c <'xmakefile'`; then
- echo shar: \"'xmakefile'\" unpacked with wrong size!
- fi
- # end of 'xmakefile'
- fi
- echo shar: End of archive 18 \(of 22\).
- cp /dev/null ark18isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 22 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
-
- exit 0 # Just in case...
-